﻿namespace BorgExt.Behaviors
{
    public abstract class Behavior<T>
        : IBehavior
    {
        protected Behavior(IRule<T> rule)
        {
            Rule = rule;
            Rule.Compose = Compose;
            Rule.Decompose = Decompose;
        }

        public virtual void Activated(ExtensionEventArgs args)
        { }

        public virtual void Activating(ExtensionEventArgs args)
        { }

        public virtual void Bind(Composer composer)
        {
            Runtime = composer.Runtime;
            Rule.Bind(composer);
        }

        public virtual void Bind(Slot slot)
        {
            BehaviorSlot = slot;
            Runtime = slot.Runtime;
            Rule.Bind(slot);
        }

        public virtual bool CanActivate(ExtensionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanClose(SlotEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanDeactivate(ExtensionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanDeselect(CompositionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanOpen(SlotEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanPlug(CompositionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanSelect(CompositionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual bool CanUnplug(CompositionEventArgs args, out LogEventArgs log)
        {
            log = null;
            return true;
        }

        public virtual void Closed(SlotEventArgs args)
        { }

        public virtual void Closing(SlotEventArgs args)
        { }

        protected virtual void Compose(T item)
        { }

        public virtual void Deactivated(ExtensionEventArgs args)
        { }

        public virtual void Deactivating(ExtensionEventArgs args)
        { }

        protected virtual void Decompose(T item)
        { }

        public virtual void Deselected(CompositionEventArgs args)
        { }

        public virtual void Deselecting(CompositionEventArgs args)
        { }

        public virtual void Opened(SlotEventArgs args)
        { }

        public virtual void Opening(SlotEventArgs args)
        { }

        public virtual void Plugged(CompositionEventArgs args)
        { }

        public virtual void Plugging(CompositionEventArgs args)
        { }

        public virtual void Selected(CompositionEventArgs args)
        { }

        public virtual void Selecting(CompositionEventArgs args)
        { }

        public virtual void Unbind(Composer composer)
        {
            Rule.Unbind(composer);
            Runtime = null;
        }

        public virtual void Unbind(Slot slot)
        {
            Rule.Unbind(slot);
            Runtime = null;
            BehaviorSlot = null;
        }

        public virtual void Unplugged(CompositionEventArgs args)
        { }

        public virtual void Unplugging(CompositionEventArgs args)
        { }

        public Slot BehaviorSlot { get; private set; }

        public Composer Composer
        {
            get { return BehaviorSlot.Runtime.Composer; }
        }

        public InstanceStore InstanceStore
        {
            get { return BehaviorSlot.Runtime.InstanceStore; }
        }

        public IRule<T> Rule { get; private set; }

        public Runtime Runtime { get; private set; }

        public TypeStore TypeStore
        {
            get { return BehaviorSlot.Runtime.TypeStore; }
        }
    }
}

